home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / fwcp / src / cp.c next >
Text File  |  1995-03-09  |  6KB  |  271 lines

  1. #include    <stdio.h>
  2. #include    <stdarg.h>
  3. #include    <string.h>
  4. #include    <errno.h>
  5. #include    <dos.h>
  6. #include    <fcntl.h>
  7. #include    <share.h>
  8. #include    "dir.h"
  9.  
  10. #define TRUE        1
  11. #define FALSE        0
  12. #define ERR        (-1)
  13.  
  14. #define    IO_BUFF_SIZE    (16 * 1024)
  15.  
  16. static    char    *prog_name = "cp";
  17. static    int    force_flg     = TRUE;
  18. static    int    recursive_flg = TRUE;
  19. static    int    verbose_flg   = TRUE;
  20. static    int    update_flg    = FALSE;
  21. static    int    verify_flg    = FALSE;
  22. static    int    check_flg     = TRUE;
  23. static    char    io_buff[IO_BUFF_SIZE];
  24.  
  25.     char    *strform(char *tmp, char *str, int max);
  26.  
  27. /************
  28. static    void    message(char *form, ...)
  29. {
  30.     va_list arg;
  31.     char    tmp[128];
  32.  
  33.     va_start(arg, form);
  34.     vsprintf(tmp, form, arg);
  35.     va_end(arg);
  36.     BEEP();
  37.     SYSLINE(tmp);
  38. }
  39. *************/
  40. char    *file_name(char *file)
  41. {
  42.     static char tmp[42];
  43.  
  44.     return strform(tmp, file, 40);
  45. }
  46. static    int    file_error(char *file)
  47. {
  48.     message("%s : %s", file_name(file), strerror(errno));
  49.     return ERR;
  50. }
  51. int    file_copy(char *src_file, char *dis_file)
  52. {
  53.     int    sfp, dfp;
  54.     int    ch, rc = 0;
  55.     unsigned read_size, write_size;
  56.     unsigned long file_size = 0L;
  57.     DIRECT st, dt;
  58.  
  59.     if ( strcmp(src_file, dis_file) == 0 ) {
  60.     message("%s -> %s\n重複したコピ-は出来ません", src_file, dis_file);
  61.     return ERR;
  62.     }
  63.  
  64.     if ( abort_check() )
  65.     return ERR;
  66.  
  67.     if ( dos_stat(src_file, &st) )
  68.     return file_error(src_file);
  69.  
  70.     if ( _dos_open(src_file, O_RDONLY, &sfp) )
  71.     return file_error(src_file);
  72.  
  73.     if ( _dos_creatnew(dis_file, st.d_att, &dfp) ) {
  74.     if ( check_flg && !dos_stat(dis_file, &dt) ) {
  75.         BEEP();
  76.         for ( ; ; ) {
  77.         verbose("'%s' overwrite ? %s", file_name(dis_file),
  78.             (rc == 0 ? "([Yes]/No) ?" : "(Yes/[No]) ?"));
  79.         if ( (ch = yesno(&rc)) == ERR )
  80.             return ERR;
  81.         else if ( ch == TRUE )
  82.             break;
  83.         }
  84.     }
  85.     if ( update_flg != FALSE && !dos_stat(dis_file, &dt) &&
  86.         st.d_att == dt.d_att && st.d_size == dt.d_size &&
  87.         st.d_date <= dt.d_date && st.d_time <= dt.d_time ) {
  88.         _dos_close(sfp);
  89.         return FALSE;
  90.     }
  91.     if ( force_flg == FALSE || _dos_creat(dis_file, st.d_att, &dfp) ) {
  92.         _dos_close(sfp);
  93.         return file_error(dis_file);
  94.     }
  95.     }
  96.  
  97.     if ( verbose_flg != FALSE )
  98.     verbose("COPY %s", file_name(dis_file));
  99.  
  100.     for ( ; ; ) {
  101.     if ( _dos_read(sfp, io_buff, IO_BUFF_SIZE, &read_size) ) {
  102.         file_error(src_file);
  103.         goto ERROR;
  104.     }
  105.  
  106.     if ( read_size == 0 )
  107.         break;
  108.  
  109.     if ( _dos_write(dfp, io_buff, read_size, &write_size) ) {
  110.         file_error(dis_file);
  111.         goto ERROR;
  112.     }
  113.  
  114.     if ( read_size != write_size ) {
  115.         message("%s : disk full ?", file_name(dis_file));
  116.         goto ERROR;
  117.     }
  118.  
  119.     if ( verbose_flg != FALSE )
  120.         scale((unsigned long)read_size);
  121.  
  122.     file_size += read_size;
  123.     }
  124.  
  125.     if ( st.d_size != file_size ) {
  126.     message("%s : file read error ?", file_name(src_file));
  127.     goto ERROR;
  128.     }
  129.  
  130.     if ( _dos_setftime(dfp, st.d_date, st.d_time) ) {
  131.     file_error(dis_file);
  132.     goto ERROR;
  133.     }
  134.  
  135.     _dos_close(sfp);
  136.     _dos_close(dfp);
  137.  
  138.     return FALSE;
  139.  
  140. ERROR:
  141.     _dos_close(sfp);
  142.     _dos_close(dfp);
  143.  
  144.     if ( unlink(dis_file) )
  145.     file_error(dis_file);
  146.  
  147.     return ERR;
  148. }
  149. static    int    chkdir(char *dir)
  150. {
  151.     int ch;
  152.     int rc = 0;
  153.     DIRECT st;
  154.  
  155.     if ( !dos_stat(dir, &st) ) {
  156.     if ( !IS_DIR((&st)) ) {
  157.         message("%s : not directory", file_name(dir));
  158.         return ERR;
  159.     }
  160.  
  161.     if ( check_flg ) {
  162.         BEEP();
  163.         for ( ; ; ) {
  164.         verbose("%s : copy directory %s", file_name(dir),
  165.             (rc == 0 ? "([Yes]/No) ?" : "(Yes/[No]) ?"));
  166.         if ( (ch = yesno(&rc)) == ERR )
  167.             return ERR;
  168.         else if ( ch == TRUE )
  169.             break;
  170.         }
  171.     }
  172.  
  173.     } else {
  174.     if ( mkdir(dir) )
  175.         return file_error(dir);
  176.     }
  177.  
  178.     return FALSE;
  179. }
  180. static    int    dir_cmp(char *src, char *dis)
  181. {
  182.     while ( *src != '\0' ) {
  183.     if ( *(src++) != *(dis++) )
  184.         return FALSE;
  185.     }
  186.  
  187.     if ( *dis == '\0' || *dis == '\\' )
  188.     return TRUE;
  189.  
  190.     return FALSE;
  191. }
  192. int    root_check(char *dir)
  193. {
  194.     return (dir[0] == '.' && (dir[1] == '.' || dir[1] == '\0') ? TRUE : FALSE);
  195. }
  196. int    dir_copy(char *src_dir, char *dis_dir)
  197. {
  198.     DIR    *dir;
  199.     DIRECT *dp;
  200.     DIRECT st;
  201.     unsigned long sz;
  202.     char   src_file[128];
  203.     char   dis_file[128];
  204.  
  205.     if ( dir_cmp(src_dir, dis_dir) ) {
  206.     message("%s -> %s\n重複したコピ-は出来ません", src_dir, dis_dir);
  207.     return ERR;
  208.     }
  209.  
  210.     if ( abort_check() )
  211.     return ERR;
  212.  
  213.     if ( chkdir(dis_dir) )
  214.     return ERR;
  215.  
  216.     if ( (dir = opendir(src_dir, 0)) == NULL )
  217.     return file_error(src_dir);
  218.  
  219.     while ( (dp = readdir(dir)) != NULL ) {
  220.     if ( root_check(dp->d_name) )
  221.         continue;
  222.  
  223.     strcpy(src_file, path_make(src_dir, dp->d_name));
  224.     strcpy(dis_file, path_make(dis_dir, dp->d_name));
  225.  
  226.     if ( IS_DIR(dp) ) {
  227.         if ( recursive_flg == FALSE )
  228.         continue;
  229.         if ( dir_copy(src_file, dis_file) )
  230.         goto ERROR;
  231.         continue;
  232.     }
  233.  
  234.     if ( file_copy(src_file, dis_file) )
  235.         goto ERROR;
  236.     }
  237.  
  238.     closedir(dir);
  239.     return FALSE;
  240.  
  241. ERROR:
  242.     closedir(dir);
  243.     return ERR;
  244. }
  245. unsigned long    dir_size(char *src_dir)
  246. {
  247.     DIR    *dir;
  248.     DIRECT *dp;
  249.     unsigned long sz = 0;
  250.     char   tmp[128];
  251.  
  252.     if ( (dir = opendir(src_dir, 0)) == NULL )
  253.     return file_error(src_dir);
  254.  
  255.     if ( verbose_flg != FALSE )
  256.     verbose("SIZE %s...", file_name(src_dir));
  257.  
  258.     while ( (dp = readdir(dir)) != NULL ) {
  259.     if ( root_check(dp->d_name) )
  260.         continue;
  261.     if ( IS_DIR(dp) )
  262.         sz += dir_size(strcpy(tmp, path_make(src_dir, dp->d_name)));
  263.     else
  264.         sz += dp->d_size;
  265.     }
  266.  
  267.     closedir(dir);
  268.  
  269.     return sz;
  270. }
  271.